Skip to content

fix : Add Groups filter to CustomResourceDefinition reconciler#937

Open
SatabdiG wants to merge 1 commit intocrossplane:mainfrom
SatabdiG:fix-customgatereconciler-filter
Open

fix : Add Groups filter to CustomResourceDefinition reconciler#937
SatabdiG wants to merge 1 commit intocrossplane:mainfrom
SatabdiG:fix-customgatereconciler-filter

Conversation

@SatabdiG
Copy link

@SatabdiG SatabdiG commented Feb 26, 2026

Description of your changes

Fixes #910

What this fix does?
The customresourcesgate reconciler was watching all CRDs cluster-wide with no filtering. This caused unnecessary reconcile cycles whenever any CRD event occurred — including CRDs from unrelated providers like cert-manager, flux, or other Crossplane providers installed in the same cluster.

Fix
Adds a Groups []string field to controller.Options. When set, the CRD gate controller applies a predicate that filters watch events to only CRDs belonging to the specified API groups.

Note
Provider authors need to populate Groups in their main.go. upjet-based providers can be fixed upstream in code generation in a follow-up PR.

Docs tracking issue: 1067

I have:

Need help with this checklist? See the cheat sheet.

@SatabdiG SatabdiG marked this pull request as ready for review February 26, 2026 12:47
@SatabdiG SatabdiG requested a review from a team as a code owner February 26, 2026 12:47
@SatabdiG SatabdiG requested a review from negz February 26, 2026 12:47
- Introduced Groups field in Options to specify API groups for CRDs.
- Implemented GroupPredicate to filter CRDs based on specified groups.
- Updated Setup function to apply the Groups filter during reconciliation.

Signed-off-by: SatabdiG <satabdi.ganguly89@gmail.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

Adds an exported Groups []string option, implements GroupPredicate(groups ...string) predicate.Predicate to filter CRDs by their spec.group, and updates the reconciler Setup to apply this predicate when Options.Groups is non-empty. Tests for the predicate behavior were added.

Changes

Cohort / File(s) Summary
Configuration
pkg/controller/options.go
Added exported field Groups []string to Options to declare which API groups the provider manages.
Filtering Logic
pkg/reconciler/customresourcesgate/setup.go
Added GroupPredicate(groups ...string) predicate.Predicate; updated Setup to apply WithEventFilter(GroupPredicate(...)) when Options.Groups is non-empty and return the builder with the filter applied.
Test Coverage
pkg/reconciler/customresourcesgate/reconciler_test.go
Added TestGroupPredicate tests covering CRD group matching, non-CRD objects, and empty-group behavior (note: file contains a duplicate test implementation).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding a Groups filter to the CustomResourceDefinition reconciler to address issue #910.
Description check ✅ Passed The description is well-related to the changeset, explaining the problem, the solution, and implementation details clearly.
Linked Issues check ✅ Passed The PR successfully addresses issue #910 by implementing CRD filtering via the Groups field and GroupPredicate, reducing unnecessary reconciles.
Out of Scope Changes check ✅ Passed All changes are directly scoped to addressing the filtering requirement: new Groups field, GroupPredicate function, and comprehensive test coverage.
Breaking Changes ✅ Passed PR introduces only additive changes to the public API without breaking modifications. New Groups field and GroupPredicate() function are backward compatible.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
pkg/reconciler/customresourcesgate/reconciler_test.go (1)

567-647: Good test coverage for GroupPredicate — one question about event type coverage.

Thanks for the comprehensive test cases! The table-driven structure follows Crossplane conventions nicely, and the test cases cover the key scenarios well:

  • ✅ CRD group present in filter
  • ✅ CRD group absent from filter
  • ✅ Empty groups list
  • ✅ Non-CRD object handling

One curiosity: I noticed the test only exercises got.Generic(ev). Since predicate.NewPredicateFuncs applies the same function to all event types (Create, Update, Delete, Generic), this should be fine in practice. However, would you consider adding at least one test case that exercises Create or Update events to document that the predicate is applied consistently across event types? This could help future maintainers understand that the filtering applies to all watch events.

Totally optional — what are your thoughts?

💡 Example of testing Create event (optional)
"CRDGroupPresentCreateEvent": {
    reason: "CRD is present in the specified groups for Create event",
    args: args{
        groups: []string{"example.com"},
        obj: &apiextensionsv1.CustomResourceDefinition{
            Spec: apiextensionsv1.CustomResourceDefinitionSpec{
                Group: "example.com",
            },
        },
    },
    want: want{
        match: true,
    },
},

Then in the test loop, you could add:

createEv := event.CreateEvent{Object: tc.args.obj}
if got.Create(createEv) != tc.want.match {
    // ...
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/reconciler/customresourcesgate/reconciler_test.go` around lines 567 -
647, Add an extra assertion in TestGroupPredicate to exercise at least one
non-Generic event (e.g., Create or Update) so the predicate behavior across
event types is documented; locate the GroupPredicate(...) call and the existing
ev := event.GenericEvent{Object: tc.args.obj} and add a corresponding createEv
:= event.CreateEvent{Object: tc.args.obj} (or updateEv) and assert
got.Create(createEv) (or got.Update(updateEv)) equals tc.want.match, failing the
test with the same cmp.Diff-based message if it does not match.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/reconciler/customresourcesgate/reconciler_test.go`:
- Around line 567-647: Add an extra assertion in TestGroupPredicate to exercise
at least one non-Generic event (e.g., Create or Update) so the predicate
behavior across event types is documented; locate the GroupPredicate(...) call
and the existing ev := event.GenericEvent{Object: tc.args.obj} and add a
corresponding createEv := event.CreateEvent{Object: tc.args.obj} (or updateEv)
and assert got.Create(createEv) (or got.Update(updateEv)) equals tc.want.match,
failing the test with the same cmp.Diff-based message if it does not match.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8fa945b and b356036.

📒 Files selected for processing (3)
  • pkg/controller/options.go
  • pkg/reconciler/customresourcesgate/reconciler_test.go
  • pkg/reconciler/customresourcesgate/setup.go

@SatabdiG SatabdiG force-pushed the fix-customgatereconciler-filter branch from b356036 to e54f430 Compare February 26, 2026 12:53
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
pkg/reconciler/customresourcesgate/reconciler_test.go (1)

567-647: Test the predicate across all event types (Create, Update, Delete, Generic) to ensure consistent filtering behavior.

The GroupPredicate implementation uses predicate.NewPredicateFuncs(), which applies the same filtering logic to all event types during watch operations. Currently, the test covers only GenericEvent. Consider adding equivalent test cases for Create, Update, and Delete events—this will pin down behavior across all code paths the predicate actually handles in the controller.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/reconciler/customresourcesgate/reconciler_test.go` around lines 567 -
647, Extend TestGroupPredicate to exercise GroupPredicate across all event
types: for each case call the predicate's Create, Update, Delete and Generic
handlers (use event.CreateEvent, event.UpdateEvent, event.DeleteEvent,
event.GenericEvent) with appropriate Objects (for UpdateEvent provide OldObject
and Object) and assert the boolean result equals tc.want.match; locate the test
loop in TestGroupPredicate and duplicate the current GenericEvent check into
checks for got.Create, got.Update, and got.Delete so the predicate behavior is
verified for all event paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/reconciler/customresourcesgate/reconciler_test.go`:
- Around line 567-647: Extend TestGroupPredicate to exercise GroupPredicate
across all event types: for each case call the predicate's Create, Update,
Delete and Generic handlers (use event.CreateEvent, event.UpdateEvent,
event.DeleteEvent, event.GenericEvent) with appropriate Objects (for UpdateEvent
provide OldObject and Object) and assert the boolean result equals
tc.want.match; locate the test loop in TestGroupPredicate and duplicate the
current GenericEvent check into checks for got.Create, got.Update, and
got.Delete so the predicate behavior is verified for all event paths.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b356036 and e54f430.

📒 Files selected for processing (3)
  • pkg/controller/options.go
  • pkg/reconciler/customresourcesgate/reconciler_test.go
  • pkg/reconciler/customresourcesgate/setup.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/controller/options.go
  • pkg/reconciler/customresourcesgate/setup.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CustomResourceGate reconcilers should filter by owned CRDs

1 participant